﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Diagnostics;

namespace iPhoneUI.Shell
{
    public abstract class Config : IHasXmlNode
    {
        private XmlNode m_config;

        private Config()
        {
        }

        protected Config(XmlNode config)
        {
            Debug.Assert(config != null);
            m_config = config;
        }

        public string Name
        {
            get
            {
                Debug.Assert(m_config.Attributes["Name"] != null);
                return m_config.Attributes["Name"].InnerText;
            }
        }

        public IEnumerable<PropertyConfig> Properties
        {
            get
            {
                return GetList<PropertyConfig>(n => new PropertyConfig(n), "property");
            }
        }

        protected string GetValue(string xpath)
        {
            XmlNode node = m_config.SelectSingleNode(xpath);
            return node != null ? node.InnerText : string.Empty;
        }

        protected string GetValue(string xpath, string defaultValue)
        {
            return GetValue(xpath, defaultValue, d => d);
        }

        protected byte GetValue(string xpath, byte defaultValue)
        {
            return GetValue(xpath, defaultValue, d => XmlConvert.ToByte(d));
        }

        protected bool GetValue(string xpath, bool defaultValue)
        {
            return GetValue(xpath, defaultValue, d => XmlConvert.ToBoolean(d));
        }

        protected int GetValue(string xpath, int defaultValue)
        {
            return GetValue(xpath, defaultValue, d => XmlConvert.ToInt32(d));
        }

        protected double GetValue(string xpath, double defaultValue)
        {
            return GetValue(xpath, defaultValue, d => XmlConvert.ToDouble(d));
        }

        protected Enum GetValue(string xpath, Enum defaultValue)
        {
            return GetValue(xpath, defaultValue, d => (Enum)Enum.Parse(defaultValue.GetType(), d, true));
        }

        protected T GetValue<T>(string xpath, T defaultValue, Func<string, T> convert)
        {
            string value = GetValue(xpath);
            if (string.IsNullOrEmpty(value) == false)
                return convert(value);

            return defaultValue;
        }

        protected IEnumerable<T> GetList<T>(Func<XmlNode, T> convert, string xpath)
        {
            return m_config.Convert<T>(convert, xpath);
        }

        public XmlNode GetNode()
        {
            return m_config;
        }
    }
}
